package com.example.onlinemonitoring.comCenter;

import java.text.ParseException;
import java.util.Date;
import java.util.concurrent.TimeUnit;

import com.example.onlinemonitoring.Util.CRC16;
import com.example.onlinemonitoring.Util.CommPortManager;
import com.example.onlinemonitoring.Util.HexUtil;
import com.example.onlinemonitoring.model.Appdevice;
import com.example.onlinemonitoring.model.Dlqjxtxhistory;
import com.example.onlinemonitoring.model.Dlqjxtxsensor;
import com.example.onlinemonitoring.serviceImpl.DlqjxtxsensorServiceImpl;
import com.example.onlinemonitoring.Util.IEEE754Utils;
import lombok.Data;

import org.springframework.context.annotation.Scope;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

/**
 * freemarker填充
 */
@Service("dlqjxtxCom")
@Scope("prototype")
public class DlqjxtxCom extends CommPortManager {
    @Autowired
    private DlqjxtxsensorServiceImpl dlqjxtxserviceimpl;

    public void receiveDatas(String str) {
        str = str.toUpperCase();
        setText(str);
        String addrstr = str.substring(0, 2);
        Integer addrint = parsePHex4(addrstr);
        reSend[addrindex] = 0;
        addrindex++;
        String cmdstr = str.substring(2, 4);
        Integer cmdint = parsePHex4(cmdstr);
        byte[] carr = HexUtil.hexString2Bytes(str);
        Date dt = new Date();
        Dlqjxtxsensor dlqjxtx = new Dlqjxtxsensor();
        dlqjxtx.setStationid(ad.getStationid());
        dlqjxtx.setDevicegroup(ad.getDevicegroup());
        dlqjxtx.setDeviceaddr(addrint);
        Dlqjxtxsensor record = dlqjxtxserviceimpl.getModel(dlqjxtx);
        dlqjxtx.setLastdatatime(dt);
        str=str.substring(6, str.length()-4);
        switch (cmdint) {
            case 3: //freemarker填充
                int startindex = 0;//freemarker填充
                dlqjxtx.setLastopenorclose(parsePHex4(str.substring(startindex, startindex+=4)));// 断路器分合状态
                dlqjxtx.setLaststorage(parsePHex4(str.substring(startindex, startindex+=4)));// 断路器储能状态
                dlqjxtx.setLastclosingcircuit(parsePHex4(str.substring(startindex, startindex+=4)));// 合闸回路状态
                dlqjxtx.setLastopeningcircuit(parsePHex4(str.substring(startindex, startindex+=4)));// 分闸回路状态
                dlqjxtx.setLastclosingcount(parsePHex4(str.substring(startindex, startindex+=4)));// 断路器合闸次数
                dlqjxtx.setLastclosingtime(parsePHex4(str.substring(startindex, startindex+=4)) * 0.1f);// 合闸时间
                dlqjxtx.setLastclosingspeed(parsePHex4(str.substring(startindex, startindex+=4)) * 0.01f);// 合闸速度
                dlqjxtx.setLastclosingmaxcurrent(parsePHex4(str.substring(startindex, startindex+=4)) * 0.1f);// 合闸线圈峰值(最大)电流
                dlqjxtx.setLastclosingavecurrent(parsePHex4(str.substring(startindex, startindex+=4)) * 0.1f);// 合闸线圈平均电流
                String cdate = str.substring(startindex, startindex+=4);
                cdate += str.substring(startindex, startindex+=4);
                cdate += str.substring(startindex, startindex+=4);
                dlqjxtx.setLastclosingdate(tosdate(cdate));// 合闸发生时间
                dlqjxtx.setLastclosingeffcurrent(parsePHex4(str.substring(startindex, startindex+=4)) * 0.1f);// 合闸前一次有效电流
                dlqjxtx.setLastopeningcount(parsePHex4(str.substring(startindex, startindex+=4)));// 断路器分闸次数
                dlqjxtx.setLastopeningtime(parsePHex4(str.substring(startindex, startindex+=4)) * 0.1f);// 分闸时间
                dlqjxtx.setLastopeningspeed(parsePHex4(str.substring(startindex, startindex+=4)) * 0.01f);// 分闸速度
                dlqjxtx.setLastopeningmaxcurrent(parsePHex4(str.substring(startindex, startindex+=4)) * 0.1f);// 分闸线圈峰值(最大)电流
                dlqjxtx.setLastopeningavecurrent(parsePHex4(str.substring(startindex, startindex+=4)) * 0.1f);// 分闸线圈平均电流
                String odate = str.substring(startindex, startindex+=4);
                odate += str.substring(startindex, startindex+=4);
                odate += str.substring(startindex, startindex+=4);
                dlqjxtx.setLastopeningdate(tosdate(odate));// 分闸发生时间
                dlqjxtx.setLastopeningeffcurrent(parsePHex4(str.substring(startindex, startindex+=4)) * 0.1f);// 分闸前一次有效电流
                dlqjxtx.setLaststoragecount(parsePHex4(str.substring(startindex, startindex+=4)));// 断路器储能次数
                dlqjxtx.setLaststoragetime(parsePHex4(str.substring(startindex, startindex+=4)) * 0.1f);// 储能时间
                dlqjxtx.setLaststoragemaxcurrent(parsePHex4(str.substring(startindex, startindex+=4)) * 0.1f);// 储能电机峰值(最大)电流
                dlqjxtx.setLaststorageavecurrent(parsePHex4(str.substring(startindex, startindex+=4)) * 0.1f);// 储能电机平均电流
                String sdate = str.substring(startindex, startindex+=4);
                sdate += str.substring(startindex, startindex+=4);
                sdate += str.substring(startindex, startindex+=4);
                dlqjxtx.setLaststoragedate(tosdate(sdate));// 储能发生时间

                dlqjxtx.setLastcommunicationstatus(0);
                dlqjxtx.setLasthisdatatime(addHistory(dlqjxtx));
                setText("设备返回数据： 站点号：1 监测点" + addrint);
                setText("合闸时间" + dlqjxtx.getLastclosingtime());
                setText("合闸速度" + dlqjxtx.getLastclosingspeed());
                setText("合闸线圈峰值(最大)电流" + dlqjxtx.getLastclosingmaxcurrent());
                setText("合闸线圈平均电流" + dlqjxtx.getLastclosingavecurrent());
                setText("合闸前一次有效电流" + dlqjxtx.getLastclosingeffcurrent());
                setText("分闸时间" + dlqjxtx.getLastopeningtime());
                setText("分闸速度" + dlqjxtx.getLastopeningspeed());
                setText("分闸线圈峰值(最大)电流" + dlqjxtx.getLastopeningmaxcurrent());
                setText("分闸线圈平均电流" + dlqjxtx.getLastopeningavecurrent());
                setText("分闸前一次有效电流" + dlqjxtx.getLastopeningeffcurrent());
                setText("储能时间" + dlqjxtx.getLaststoragetime());
                setText("储能电机峰值(最大)电流" + dlqjxtx.getLaststoragemaxcurrent());
                setText("储能电机平均电流" + dlqjxtx.getLaststorageavecurrent());
                break;
            default:
                break;
        }
        dlqjxtxserviceimpl.Update(dlqjxtx, false);
    }
    private Date addHistory(Dlqjxtxsensor sensor) {
        sensor = dlqjxtxserviceimpl.getModel(sensor);
        if (sensor != null) {
            if (sensor.getLasthisdatatime() == null) {
                add(sensor);
                return new Date();
            } else {
                long lasttime = 0;
                long nowtime = 0;
                try {
                    lasttime = HexUtil.todate(sensor.getLasthisdatatime()).getTime();
                    nowtime = HexUtil.todate(new Date()).getTime();
                } catch (ParseException e) {
                    e.printStackTrace();
                }
                int timersp = 60000;
                if (sensor.getLastalarmlevel() != 0) {
                    timersp = ad.getHisalarmtimersp()*1000;
                } else {
                    timersp = ad.getHistimersp()*1000;
                }
                if (lasttime + timersp < nowtime) {
                    add(sensor);
                    return new Date();
                }
            }
        }
        return null;
    }
    private void add(Dlqjxtxsensor sensor) {
        Dlqjxtxhistory his = new Dlqjxtxhistory();
        his.setStationid(sensor.getStationid());
        his.setDevicegroup(sensor.getDevicegroup());
        his.setDeviceaddr(sensor.getDeviceaddr());
        his.setAlarmlevel(sensor.getLastalarmlevel());
        his.setAlarmmessage(sensor.getLastalarmmessage());
        his.setDatatime(sensor.getLastdatatime());
        his.setPointname(sensor.getPointname());

        //需要添加自己定义的属性
        //  todo
        his.setClosingtime(sensor.getLastclosingtime());
        his.setClosingspeed(sensor.getLastclosingspeed());
        his.setClosingmaxcurrent(sensor.getLastclosingmaxcurrent());
        his.setClosingavecurrent(sensor.getLastclosingavecurrent());
        his.setClosingeffcurrent(sensor.getLastclosingeffcurrent());
        his.setOpeningtime(sensor.getLastopeningtime());
        his.setOpeningspeed(sensor.getLastopeningspeed());
        his.setOpeningmaxcurrent(sensor.getLastopeningmaxcurrent());
        his.setOpeningavecurrent(sensor.getLastopeningavecurrent());
        his.setOpeningeffcurrent(sensor.getLastopeningeffcurrent());
        his.setStoragetime(sensor.getLaststoragetime());
        his.setStoragemaxcurrent(sensor.getLaststoragemaxcurrent());
        his.setStorageavecurrent(sensor.getLaststorageavecurrent());
        his.setOpenorclose(sensor.getLastopenorclose());
        his.setStorage(sensor.getLaststorage());
        his.setClosingcircuit(sensor.getLastclosingcircuit());
        his.setOpeningcircuit(sensor.getLastopeningcircuit());
        his.setClosingcount(sensor.getLastclosingcount());
        his.setClosingdate(sensor.getLastclosingdate());
        his.setOpeningcount(sensor.getLastopeningcount());
        his.setOpeningdate(sensor.getLastopeningdate());
        his.setStoragecount(sensor.getLaststoragecount());
        his.setStoragedate(sensor.getLaststoragedate());
        dlqjxtxserviceimpl.Add(his);
    }

    @Async("threadPool")
    public void startSendThread(Appdevice Appdevice) throws Exception {
        String cmd[] = new String[3];
        cmd[0] = "%s0300640032";// 遥信  freemarker填充
        checkType = "crc16";
        issend.put(Thread.currentThread().getId(), true);
        String cstr = "";
        int timeoutsp = (int) Math.round(Appdevice.getTimeoutsp() * 1000);
        timersp = (int) Math.round(Appdevice.getTimersp() * 1000);
        while (issend.get(Thread.currentThread().getId()) != null) {
            rlock.lock();
            try {
                if (isrun) {
                    if (addrindex > Appdevice.getAddrmax() || addrindex < Appdevice.getAddrmin())
                        addrindex = Appdevice.getAddrmin();
                    cstr = String.format(cmd[currcmd], String.format("%02X", addrindex));
                    cstr = cstr + CRC16.calcCrc16(cstr);
                    Send(cstr);
                    sendCondition.await(timeoutsp,TimeUnit.MILLISECONDS);
                    currcmd = 0;
                    if (reSend[addrindex] > 3) {
                        dlqjxtxserviceimpl.UpdateStatus(ad, addrindex, 1);
                        reSend[addrindex] = 0;
                        addrindex++;
                    }
                    reSend[addrindex]++;
                } else if (rescode != 0) {
                    setText(resmsg[rescode]);
                }
            } catch (Exception e) {
                // TODO: handle exception
            }finally{
                rlock.unlock();
            }
        }
    }
}